using System;
using System.Collections.Generic;

namespace Gloom
{
	public static class ManagedUnmanagedTypeTranslator
	{
		private static long unique = -1;
		
		public static string GetArgTranslatePattern(string managedType, string unmanagedType, out string returnPrefix, out string returnPostfix, out bool lateReturn)
		{
			returnPrefix = "";
			returnPostfix = "";
			lateReturn = false;
			
			if (unmanagedType.StartsWith("out "))
			{
				/*if (managedType.EndsWith("[]")) // implying managedType starts with ref, too...
				{
					unique++;
					returnPrefix = unmanagedType.Substring(4) + " ip" + unique + ";\n\t\t\t";
					returnPostfix = "\n\t\t\tfixed (" + managedType.Substring(4).Replace("[]", "*") + " ptr" + unique + " = &$[0]) { "
						+ "ptr" + unique + " = ip" + unique + ".ToPointer(); } ";
					return "out ip" + unique;
				}
				else */
				if (managedType == "out bool[]" && unmanagedType == "out byte*") // Ref => out, so only the out matters!!
				{
					unique++;
					returnPrefix = "byte[] btr" + unique + " = new byte[1];\n\t\t\tfixed (" + unmanagedType.Substring(4).Replace("[]", "*") + " optr"
						+ unique + " = btr" + unique + ") { ";
					returnPostfix = " }\n\t\t\t$ = new bool[btr" + unique + ".Length];\n\t\t\tfor (int i" + unique + " = 0; i" + unique
						+ "< $.Length; i" + unique + "++)\n\t\t\t\t$[i" + unique + "] = (btr" + unique + "[i" + unique + "] == 1);\n\t\t\t ";
					lateReturn = true;
					return "optr" + unique;
				}
				else if (managedType == "out GLEnum[]" && unmanagedType == "out uint*") // Ref => out, so only the out matters!!
				{
					unique++;
					returnPrefix = "uint[] unt" + unique + " = new uint[$.Length];\n\t\t\tfixed (uint* ptr" + unique + " = unt" + unique + ") { ";
					returnPostfix = " } \n\t\t\tfor (int i = 0; i < unt" + unique + ".Length; i++)\n\t\t\t\t"
						+ "$[i] = (GLEnum)unt" + unique + "[i];\n\t\t\t";
					lateReturn = true;
					return "ptr" + unique;
				}
				else if (managedType == "out IntPtr" && unmanagedType == "out IntPtr") // BROKE, TBH
				{
					return "$";
				}
				else
				{
					unique++;
					returnPrefix = "fixed (" + managedType.Substring(4).Replace("[]", "*") + " optr" + unique + " = $) { ";
					returnPostfix = " } ";
					return "optr" + unique;
				}
			}
			
			if (managedType == unmanagedType)
				return "$";
			else if (managedType == "bool" && unmanagedType == "byte")
				return "$ ? ((byte)1) : ((byte)0)";
			else if (managedType.EndsWith("[]")) // implying unmanagedType == IntPtr
			{
				unique++;
				returnPrefix = "fixed (" + managedType.Replace("[]", "*") + " ptr" + unique + " = &$[0]) { ";
				returnPostfix = " } ";
				return "new IntPtr(ptr" + unique + ")";
			}
			else // nothing special? then just try to cast...
			{
				return "(" + unmanagedType + ")$";
			}
		}
		
		public static string GetRetTranslatePattern(string managedType, string unmanagedType, out string returnPrefix, out string returnPostfix)
		{
			returnPrefix = "";
			returnPostfix = "";
			
			// TODO: Fill out more
			if (managedType == unmanagedType || managedType == "void")
				return "$";
			else if (managedType == "bool" && unmanagedType == "byte")
				return "($ == 1)";
			else
				return "(" + managedType + ") $";
			
			//throw new NotImplementedException();
		}
	}
}

